home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* */
- /* ------------ Bit-Bucket Software <no-Inc> */
- /* \ 10001101 / Writers and Distributors of */
- /* \ 011110 / No-Cost<no-tm> Software. */
- /* \ 1011 / */
- /* ------ KopyRong (K) 1987. ALL RIGHTS REVERSED. */
- /* */
- /* */
- /* This module was written by Bob Hartman */
- /* */
- /* */
- /* BinkleyTerm Scheduler Routines */
- /* */
- /* */
- /* This software package is being distributed WITH FULL SOURCE CODE */
- /* with the following conditions: 1) If anything awful happens */
- /* because you use it (or don't use it), you accept full */
- /* responsibility; 2) you don't start making tons of voice calls to */
- /* the authors to complain or make suggestions about enhancements, */
- /* useful or otherwise; 3) you do not reuse this code in commercial */
- /* products without specific permission to do so from the authors; */
- /* 4) If you find any problems you send fixes to the authors for */
- /* inclusion in updates; 5) You find some way to express your */
- /* appreciation for this method of distribution, either by writing */
- /* code or application notes, or just sending along a "Thank You" */
- /* message. */
- /* */
- /* There is copyrighted code in this product. We either wrote it */
- /* ourselves or got permission to use it. Please don't force us to */
- /* pay a lawyer -- have some respect for our motives and don't abuse */
- /* this "license". */
- /* */
- /* */
- /*--------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/utime.h>
- #include "sched.h"
-
- extern char *skip_blanks();
- extern char *BINKpath;
-
- EVENT *e_ptrs[256];
- int num_events = 0;
- int cur_event = -1;
- int got_sched = 0;
- int noforce = 0;
- int max_connects = 3;
- int max_noconnects = 10000;
-
- extern char no_requests;
- extern char *skip_blanks();
-
- char *skip_to_blank (string)
- char *string;
- {
- while (*string && (!isspace (*string)))
- ++string;
- return (string);
- }
-
- char *start_time (e, p)
- EVENT *e;
- char *p;
- {
- int i, j;
-
- if (sscanf (p, "%d:%d", &i, &j) != 2)
- {
- return NULL;
- }
-
- e->minute = i*60+j;
- if ((e->minute < 0) || (e->minute > (24*60)))
- {
- return (NULL);
- }
-
- p = skip_to_blank (p);
-
- return (p);
- }
-
- char *end_time (e, p)
- EVENT *e;
- char *p;
- {
- int i, j, k;
-
- if (sscanf (p, "%d:%d", &i, &j) != 2)
- {
- return NULL;
- }
-
- k = i*60+j;
- if ((k > (24*60)) || (k < 0))
- {
- return (NULL);
- }
-
- if (k < e->minute)
- {
- printf ("Ending time wraps through midnight - not allowed\n");
- return (NULL);
- }
-
- e->length = k - e->minute;
-
- p = skip_to_blank (p);
-
- return (p);
- }
-
- parse_event (e_line)
- char *e_line;
- {
- int i, j, j1, j2;
- char *p, *p1;
- EVENT *e;
-
- /* If we already have a schedule, then forget it */
- if (got_sched)
- return (0);
-
- /* Skip blanks to get to the days field */
- p = skip_blanks(e_line);
-
- /* Parse the days field */
- e = (EVENT *) calloc (sizeof (EVENT), 1);
- e->days = 0;
- e->wait_time = 120;
- while ((*p) && (!isspace(*p)))
- {
- switch (toupper(*p))
- {
- case 'S': /* Sunday or Saturday */
- if (!strnicmp (p, "sun", 3))
- {
- e->days |= DAY_SUNDAY;
- }
- else if (!strnicmp (p, "sat", 3))
- {
- e->days |= DAY_SATURDAY;
- }
- else /* Error condition */
- {
- goto err;
- }
- p += 3;
- break;
-
- case 'M': /* Monday */
- if (!strnicmp (p, "mon", 3))
- {
- e->days |= DAY_MONDAY;
- }
- else /* Error condition */
- {
- goto err;
- }
- p += 3;
- break;
-
- case 'T': /* Tuesday or Thursday */
- if (!strnicmp (p, "tue", 3))
- {
- e->days |= DAY_TUESDAY;
- }
- else if (!strnicmp (p, "thu", 3))
- {
- e->days |= DAY_THURSDAY;
- }
- else /* Error condition */
- {
- goto err;
- }
- p += 3;
- break;
-
- case 'W': /* Wednesday, Week or Weekend */
- if (!strnicmp (p, "wed", 3))
- {
- e->days |= DAY_WEDNESDAY;
- p += 3;
- }
- else if (!strnicmp (p, "week", 4))
- {
- e->days |= DAY_WEEK;
- p += 4;
- }
- else if (!strnicmp (p, "wkend", 5))
- {
- e->days |= DAY_WKEND;
- p += 5;
- }
- else /* Error condition */
- {
- goto err;
- }
- break;
-
- case 'F': /* Friday */
- if (!strnicmp (p, "fri", 3))
- {
- e->days |= DAY_FRIDAY;
- }
- else /* Error condition */
- {
- goto err;
- }
- p += 3;
- break;
-
- case 'A': /* All */
- if (!strnicmp (p, "all", 3))
- {
- e->days |= (DAY_WEEK|DAY_WKEND);
- }
- else /* Error condition */
- {
- goto err;
- }
- p += 3;
- break;
-
- default: /* Error condition */
- goto err;
- }
-
- if (*p == '|')
- ++p;
- }
-
- /* Did we get something valid? */
- if (e->days == 0)
- {
- goto err;
- }
-
- /* Skip blanks to get to the start-time field */
- p = skip_blanks (p);
-
- /* Parse the start-time field */
- if ((p = start_time (e, p)) == NULL)
- {
- printf ("'%s' has an invalid START-TIME\n", e_line);
- free (e);
- return (1);
- }
-
- /* Give each event a default of 60 minutes */
- e->length = 60;
-
- /* While there are still things on the line */
- while (*p)
- {
- /* Skip blanks to get to the next field */
- p = skip_blanks (p);
-
- /* switch to find what thing is being parsed */
- switch (tolower(*p))
- {
- case '\0': /* No more stuff */
- break;
-
- case '0': /* Digits must be an ending time */
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- /* Parse ending time */
- if ((p = end_time (e, p)) == NULL)
- {
- printf ("'%s' has an invalid END-TIME\n", e_line);
- free (e);
- return (1);
- }
- break;
-
- case ';': /* Comment */
- case '%':
- *p = '\0';
- break;
-
- case 'a': /* Average wait */
- ++p;
- if (*p == '=')
- {
- ++p;
- if (isdigit (*p))
- {
- i = atoi (p);
- if ((i > 240) || (i < 0))
- {
- printf ("'%s' has bad AvgWait (higher than max of 240 or less than min of 0)\n", e_line);
- free (e);
- return (1);
- }
- e->wait_time = i;
- p = skip_to_blank (p);
- break;
- }
- }
- printf ("'%s' has a bad AvgWait code\n", e_line);
- free (e);
- return (1);
-
- case 'b': /* BBS type event */
- p = skip_to_blank (p);
- e->behavior |= MAT_BBS;
- break;
-
- case 'c': /* #CM event */
- p = skip_to_blank (p);
- e->behavior |= MAT_CM;
- break;
-
- case 'd': /* Dynamic event */
- p = skip_to_blank (p);
- e->behavior |= MAT_DYNAM;
- break;
-
- case 'e': /* An errorlevel exit */
- ++p;
- if (isdigit(*p))
- {
- i = *p - '0';
- ++p;
- if ((*p == '=') && (i <= 5) && (i > 0))
- {
- ++p;
- if (isdigit (*p))
- {
- j = atoi (p);
- e->errlevel[i-1] = j;
- p = skip_to_blank (p);
- break;
- }
- }
- }
- printf ("'%s' has a bad Errorlevel code\n", e_line);
- free (e);
- return (1);
-
- case 'f': /* Forced event */
- p = skip_to_blank (p);
- e->behavior |= MAT_FORCED;
- break;
-
- case 'l': /* Local only mail */
- p = skip_to_blank (p);
- e->behavior |= MAT_LOCAL;
- break;
-
- case 'n': /* No requests */
- p = skip_to_blank (p);
- e->behavior |= MAT_NOREQ;
- break;
-
- case 'r': /* Receive only */
- p = skip_to_blank (p);
- e->behavior |= MAT_NOOUT;
- break;
-
- case 's': /* Send only */
- p = skip_to_blank (p);
- e->behavior |= MAT_OUTONLY;
- break;
-
- case 't': /* Tries */
- ++p;
- if (sscanf (p, "=%d,%d", &j1, &j2) != 2)
- {
- printf ("'%s' has a bad number of Tries\n", e_line);
- return (1);
- }
- else
- {
- if ((j1 > 8) || (j1 < 1))
- {
- printf ("'%s' has a bad number of Tries\n", e_line);
- return (1);
- }
- max_connects = j1;
- max_noconnects = j2;
- }
- p = skip_to_blank (p);
- break;
-
- default: /* Error condition */
- printf ("'%s' has something indecipherable\n", e_line);
- free (e);
- return (1);
- }
- }
-
- /* Save it in the array of pointers */
- e_ptrs[num_events++] = e;
-
- /*
- printf ("\nEvent shows:\n");
- printf (" days = %04x\n", e->days);
- printf (" minute = %d\n", e->minute);
- printf (" length = %d\n", e->length);
- for (i = 0; i < 5; i++)
- printf (" err[%d] = %d\n", i, e->errlevel[i]);
- */
-
- /* Return that everything is cool */
- return (0);
-
- err:
- printf ("'%s' has an invalid DAY field\n", e_line);
- free (e);
- return (1);
- }
-
- find_event ()
- {
- int cur_day;
- int cur_hour;
- int cur_minute;
- int cur_mday;
- int cur_mon;
- int cur_year;
- int junk, junk1;
- int our_time;
- int i;
- int j;
-
- /* Get the current time in minutes */
- dostime (&cur_hour, &cur_minute, &junk, &junk);
- our_time = cur_hour * 60 + cur_minute;
-
- /* Get the current day of the week */
- dosdate (&cur_mon, &cur_mday, &cur_year, &cur_day);
-
- /* Make the month 0 based */
- --cur_mon;
-
- cur_day = 1 << cur_day;
-
- cur_event = -1;
-
- /* Go through the events from top to bottom */
- for (i = 0; i < num_events; i++)
- {
- if (our_time >= e_ptrs[i]->minute)
- {
- if (cur_day & e_ptrs[i]->days)
- {
- if (((our_time-e_ptrs[i]->minute) < e_ptrs[i]->length) ||
- ((our_time == e_ptrs[i]->minute) && (e_ptrs[i]->length == 0)) ||
- ((e_ptrs[i]->behavior & MAT_FORCED) && (e_ptrs[i]->last_ran != cur_mday)))
- {
- /* Are we not supposed to force old events */
- if (((our_time-e_ptrs[i]->minute) > e_ptrs[i]->length) && (noforce))
- {
- e_ptrs[i]->last_ran = cur_mday;
- continue;
- }
-
- if (e_ptrs[i]->last_ran != cur_mday)
- {
- set_xy("");
- status_line (":Starting Event %d", i + 1);
-
- /* Mark that this one is running */
- e_ptrs[i]->last_ran = cur_mday;
-
- /* Write out the schedule */
- write_sched();
-
- /* If we are supposed to exit, then do it */
- if (e_ptrs[i]->errlevel[0])
- {
- status_line("#Exit at start of event with errorlevel %d",
- e_ptrs[i]->errlevel[0]);
-
- errl_exit (e_ptrs[i]->errlevel[0]);
- }
- }
- else
- {
- /* Don't do events that have been exited already */
- if (e_ptrs[i]->behavior & MAT_SKIP)
- continue;
- }
-
- cur_event = i;
-
- if (e_ptrs[i]->behavior & MAT_NOREQ)
- no_requests = 1;
- else
- no_requests = 0;
-
- break;
- }
- }
- }
- }
-
- /*
- printf("\nCurrent event is event %d\n", cur_event);
- if (cur_event >= 0)
- {
- printf ("Event shows:\n");
- printf (" days = %04x\n", e_ptrs[cur_event]->days);
- printf (" minute = %d\n", e_ptrs[cur_event]->minute);
- printf (" length = %d\n", e_ptrs[cur_event]->length);
- for (i = 0; i < 5; i++)
- printf (" err[%d] = %d\n", i, e_ptrs[cur_event]->errlevel[i]);
- }
- */
- }
-
- read_sched ()
- {
- char temp1[80], temp2[80];
- char *malloc();
- EVENT *sptr;
- struct stat buffer1, buffer2;
- FILE *f;
- int i;
-
- strcpy(temp1,BINKpath);
- strcpy(temp2,BINKpath);
- strcat(temp1,"Binkley.Scd");
- strcat(temp2,"Binkley.Cfg");
-
- if (stat (temp1, &buffer1))
- {
- return;
- }
-
- if (stat (temp2, &buffer2))
- {
- return;
- }
-
- if ((buffer1.st_atime < buffer2.st_atime) ||
- (buffer1.st_size < sizeof(EVENT)))
- {
- return;
- }
-
- if ((sptr = (EVENT *) malloc ((int) buffer1.st_size)) == NULL)
- {
- return;
- }
-
- if ((f = fopen (temp1, "rb")) == NULL)
- {
- return;
- }
-
- fread (sptr, (int) buffer1.st_size, 1, f);
- got_sched = 1;
-
- num_events = buffer1.st_size / sizeof (EVENT);
- for (i = 0; i < num_events; i++)
- {
- e_ptrs[i] = sptr++;
- }
-
- fclose (f);
- return;
- }
-
- write_sched ()
- {
- char temp1[80], temp2[80];
- FILE *f;
- int i;
- struct stat buffer1;
- struct utimbuf times;
- long t;
- extern long time();
-
- /* Get the current time */
- t = time (NULL);
-
- strcpy(temp1,BINKpath);
- strcpy(temp2,BINKpath);
- strcat(temp1,"Binkley.Scd");
- strcat(temp2,"Binkley.Cfg");
-
- /* Get the current stat for .Cfg file */
- if (!stat (temp2, &buffer1))
- {
- /* If it is newer than current time, we have a problem and
- we must reset the file date - yucky, but it will probably work */
- if (t < buffer1.st_atime)
- {
- times.actime = buffer1.st_atime;
- times.modtime = buffer1.st_atime;
- status_line ("!Date rollover problem?");
- }
- else
- {
- times.actime = t;
- times.modtime = t;
- }
- }
-
- if ((f = fopen (temp1, "wb")) == NULL)
- {
- return;
- }
-
- for (i = 0; i < num_events; i++)
- {
- /* If it is skipped, but not dynamic, reset it */
- if ((e_ptrs[i]->behavior & MAT_SKIP) &&
- (!(e_ptrs[i]->behavior & MAT_DYNAM)))
- {
- e_ptrs[i]->behavior &= ~MAT_SKIP;
- }
-
- /* Write this one out */
- fwrite (e_ptrs[i], sizeof (EVENT), 1, f);
- }
-
- fclose (f);
-
- utime (temp1, ×);
-
- return;
- }
-
- time_to_next ()
- {
- int cur_day;
- int cur_hour;
- int cur_minute;
- int cur_mday;
- int cur_mon;
- int cur_year;
- int junk, junk1;
- int our_time;
- int i;
- int time_to;
- int guess;
- int nmin;
-
- /* Get the current time in minutes */
- dostime (&cur_hour, &cur_minute, &junk, &junk);
- our_time = cur_hour * 60 + cur_minute;
-
- /* Get the current day of the week */
- dosdate (&cur_mon, &cur_mday, &cur_year, &cur_day);
-
- /* Make the month 0 based */
- --cur_mon;
-
- cur_day = 1 << cur_day;
-
- /* A ridiculous number */
- time_to = 3000;
-
- /* Go through the events from top to bottom */
- for (i = 0; i < num_events; i++)
- {
- /* If it is the current event, skip it */
- if (cur_event == i)
- continue;
-
- /* If it is a BBS event, skip it */
- if (e_ptrs[i]->behavior & MAT_BBS)
- continue;
-
- /* If it was already run today, skip it */
- if (e_ptrs[i]->last_ran == cur_mday)
- continue;
-
- /* If it doesn't happen today, skip it */
- if (!(e_ptrs[i]->days & cur_day))
- continue;
-
- /* If it is earlier than now, skip it unless it is forced */
- if (e_ptrs[i]->minute < our_time)
- {
- if (!(e_ptrs[i]->behavior & MAT_FORCED))
- {
- continue;
- }
-
- /* Hmm, found a forced event that has not executed yet */
- /* Give the guy 2 minutes and call it quits */
- guess = 2;
- }
- else
- {
- /* Calculate how far it is from now */
- guess = e_ptrs[i]->minute - our_time;
- }
-
- /* If less than closest so far, keep it */
- if (time_to > guess)
- time_to = guess;
- }
-
- /* If we still have nothing, then do it again, starting at midnight */
- if (time_to >= 1441)
- {
- /* Calculate here to midnight */
- nmin = 1440 - our_time;
-
- /* Go to midnight */
- our_time = 0;
-
- /* Go to the next possible day */
- cur_day = cur_day << 1;
- if (cur_day > DAY_SATURDAY)
- cur_day = DAY_SUNDAY;
-
- /* Go through the events from top to bottom */
- for (i = 0; i < num_events; i++)
- {
- /* If it is a BBS event, skip it */
- if (e_ptrs[i]->behavior & MAT_BBS)
- continue;
-
- /* If it doesn't happen today, skip it */
- if (!(e_ptrs[i]->days & cur_day))
- continue;
-
- /* Calculate how far it is from now */
- guess = e_ptrs[i]->minute + nmin;
-
- /* If less than closest so far, keep it */
- if (time_to > guess)
- time_to = guess;
- }
- }
-
- if (time_to > 1440)
- time_to = 1440;
-
- if (time_to < 1)
- time_to = 1;
-
- return (time_to);
- }
-
-